package export;

import java.awt.Component;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import neuron.Network;
import neuron.NetworkStatistics;
import neuron.Neuron;
import neuron.NeuronFilter;
import neuron.file.NetmorphLoader;
import neuron.file.NeuroLucidaLoader;

import matlab.Matlab5File;

public class StatisticsToMatlabExport {

	

	
	public static void exportNet(NetworkStatistics ns, File out) throws IOException
	{
		Matlab5File m5 = new Matlab5File();
		
		m5.addDoubleArray("basal_nTermSeg", ns.basalTermSegCountDist().values(), ns.basalTermSegCountDist().count(), 1);
		m5.addDoubleArray("basal_TermSegLen", ns.basalTermSegLenDist().values(), ns.basalTermSegLenDist().count(), 1);
		m5.addDoubleArray("basal_IntSegLen", ns.basalIntSegLenDist().values(), ns.basalIntSegLenDist().count(), 1);

		m5.addDoubleArray("oblique_nTermSeg", ns.obliqueTermSegCountDist().values(), ns.obliqueTermSegCountDist().count(), 1);
		m5.addDoubleArray("oblique_TermSegLen", ns.obliqueTermSegLenDist().values(), ns.obliqueTermSegLenDist().count(), 1);
		m5.addDoubleArray("oblique_IntSegLen", ns.obliqueIntSegLenDist().values(), ns.obliqueIntSegLenDist().count(), 1);

		m5.addDoubleArray("tuft_nTermSeg", ns.tuftTermSegCountDist().values(), ns.tuftTermSegCountDist().count(), 1);
		m5.addDoubleArray("tuft_TermSegLen", ns.tuftTermSegLenDist().values(), ns.tuftTermSegLenDist().count(), 1);
		m5.addDoubleArray("tuft_IntSegLen", ns.tuftIntSegLenDist().values(), ns.tuftIntSegLenDist().count(), 1);
		
		m5.addText("date", DateFormat.getDateTimeInstance().format(new Date()));
		
		
		// AGE data
		m5.addDoubleArray("age_basal_nts_per_neuron", ns.ageBasalNTSPerNeuron().values(), ns.ageBasalNTSPerNeuron().count(), 2);
		m5.addDoubleArray("age_oblique_nts_per_neuron", ns.ageObliqueNTSPerNeuron().values(), ns.ageObliqueNTSPerNeuron().count(), 2);
		m5.addDoubleArray("age_tuft_nts_per_neuron", ns.ageTuftNTSPerNeuron().values(), ns.ageTuftNTSPerNeuron().count(), 2);
		
		m5.addDoubleArray("age_basal_islen_per_neuron", ns.ageBasalISLenPerNeuron().values(), ns.ageBasalISLenPerNeuron().count(), 2);
		m5.addDoubleArray("age_oblique_islen_per_neuron", ns.ageObliqueISLenPerNeuron().values(), ns.ageObliqueISLenPerNeuron().count(), 2);
		m5.addDoubleArray("age_tuft_islen_per_neuron", ns.ageTuftISLenPerNeuron().values(), ns.ageTuftISLenPerNeuron().count(), 2);

		m5.addDoubleArray("age_basal_tslen_per_neuron", ns.ageBasalTSLenPerNeuron().values(), ns.ageBasalTSLenPerNeuron().count(), 2);
		m5.addDoubleArray("age_oblique_tslen_per_neuron", ns.ageObliqueTSLenPerNeuron().values(), ns.ageObliqueTSLenPerNeuron().count(), 2);
		m5.addDoubleArray("age_tuft_tslen_per_neuron", ns.ageTuftTSLenPerNeuron().values(), ns.ageTuftTSLenPerNeuron().count(), 2);

		
		// BRAIN SIZE data (PIA-WM)
		m5.addDoubleArray("brainsize_basal_nts_per_neuron", ns.brainsizeBasalNTSPerNeuron().values(), ns.brainsizeBasalNTSPerNeuron().count(), 2);
		m5.addDoubleArray("brainsize_oblique_nts_per_neuron", ns.brainsizeObliqueNTSPerNeuron().values(), ns.brainsizeObliqueNTSPerNeuron().count(), 2);
		m5.addDoubleArray("brainsize_tuft_nts_per_neuron", ns.brainsizeTuftNTSPerNeuron().values(), ns.brainsizeTuftNTSPerNeuron().count(), 2);
		
		m5.addDoubleArray("brainsize_basal_islen_per_neuron", ns.brainsizeBasalISLenPerNeuron().values(), ns.brainsizeBasalISLenPerNeuron().count(), 2);
		m5.addDoubleArray("brainsize_oblique_islen_per_neuron", ns.brainsizeObliqueISLenPerNeuron().values(), ns.brainsizeObliqueISLenPerNeuron().count(), 2);
		m5.addDoubleArray("brainsize_tuft_islen_per_neuron", ns.brainsizeTuftISLenPerNeuron().values(), ns.brainsizeTuftISLenPerNeuron().count(), 2);

		m5.addDoubleArray("brainsize_basal_tslen_per_neuron", ns.brainsizeBasalTSLenPerNeuron().values(), ns.brainsizeBasalTSLenPerNeuron().count(), 2);
		m5.addDoubleArray("brainsize_oblique_tslen_per_neuron", ns.brainsizeObliqueTSLenPerNeuron().values(), ns.brainsizeObliqueTSLenPerNeuron().count(), 2);
		m5.addDoubleArray("brainsize_tuft_tslen_per_neuron", ns.brainsizeTuftTSLenPerNeuron().values(), ns.brainsizeTuftTSLenPerNeuron().count(), 2);


		m5.write(out);
	}
	
	public static Network loadFile(File f) throws FileNotFoundException, IOException, ParseException
	{
		if (f.getAbsolutePath().toUpperCase().endsWith(".ASC")) {
			return NeuroLucidaLoader.load(f);
		} else if (f.getAbsolutePath().toUpperCase().endsWith(".NEURONS")) {
			return NetmorphLoader.load(f);
		}
		return null;
	}
	
	public static void export(File src, File dest) throws FileNotFoundException, IOException, ParseException
	{
		if (src.isFile()) {
			// write single mat
			Network net = loadFile(src);
			for (Neuron n : net) NeuronFilter.filterNeuron(n);
			NetworkStatistics stats = new NetworkStatistics(net);
			exportNet(stats, dest);
			
		} else {
			// write directory
			File[] files = src.listFiles(FileFilters.neuroFileFilter);
			List<Network> nets = new ArrayList<Network>();
			for (File ff : files) {
				Network net = loadFile(ff);
				for (Neuron n : net) NeuronFilter.filterNeuron(n);
				nets.add(net);
			}
			NetworkStatistics stats = new NetworkStatistics(nets);
			exportNet(stats, dest);
		}
	}
}
